package cn.school.teacher.evaluation.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.school.common.exception.ApiException;
import cn.school.common.utils.StringUtils;
import cn.school.common.utils.SysUserUtils;
import cn.school.teacher.evaluation.dao.TeacherEvaluationResultDao;
import cn.school.teacher.evaluation.entity.TeacherEvaluationGrade;
import cn.school.teacher.evaluation.entity.TeacherEvaluationResult;
import cn.school.teacher.evaluation.entity.TeacherEvaluationScheme;
import cn.school.teacher.evaluation.entity.TeacherEvaluationTask;
import cn.school.teacher.evaluation.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class TeacherEvaluationResultServiceImpl extends ServiceImpl<TeacherEvaluationResultDao, TeacherEvaluationResult> implements TeacherEvaluationResultService {
	private static Logger logger = LoggerFactory.getLogger(TeacherEvaluationResultServiceImpl.class);
	private static Boolean isProcess = false;
	
	@Autowired
	private EvaluationTaskService evaluationTaskService;
	@Autowired
	private EvaluationUserTaskService evaluationUserTaskService;
	@Autowired
	private TeacherEvaluationGradeService teacherEvaluationGradeService;
	@Autowired
	private EvaluationSchemeService evaluationSchemeService;
	
	@Override
	public void processBiz() {
		String exeUuid = UUID.randomUUID().toString();
		// ======= 加锁 =============
		synchronized (this.isProcess) {
			if (isProcess) {
				this.logger.info("===== [exeUUID:" + exeUuid + "] 绩效考核结果处理任务：正在处理，本次执行忽略！！！！！======");
				return;
			} else {
				this.isProcess = true;
			}
		}
		
		// ==== 获取考评任务获取，并生成考评结果 ========
		List<TeacherEvaluationTask> taskList = evaluationTaskService.getTeEvTaskListByNotProcess();
		int size = taskList != null ? taskList.size() : 0;
		// 处理考生成考评任务结果
		if (size != 0) {
			int index = 1;
			int successCount = 0;
			Exception eStatus = null;
			for (TeacherEvaluationTask teacherEvaluationTask : taskList) {
				try {
					this.gennerResult(teacherEvaluationTask);
					this.logger.info("===== [exeUUID:" + exeUuid + "] 绩效考核结果处理任务：生成成功【{} / {} / {}】" +
							"{taskId:{}, name:{} ======} \n ", index, ++successCount, size, teacherEvaluationTask.getId(), teacherEvaluationTask.getTetaName());
					eStatus = null;
				} catch (ApiException e) {
					eStatus = e;
				} catch (Exception e) {
					eStatus = e;
				}
				if (eStatus != null) {
					logger.warn("===== [exeUUID:" + exeUuid + "] 绩效考核结果处理任务：生成失败【{} / {} / {}】" +
							"{taskId:{}, name:{}} ====== \n {}", index, successCount, size, teacherEvaluationTask.getId(), teacherEvaluationTask.getTetaName(), eStatus.getMessage());
					if (!(eStatus instanceof ApiException)) {
						logger.error("", eStatus);
					}
				}
				index++;
			}
		} else {
			this.logger.info("===== [exeUUID:" + exeUuid + "] 绩效考核结果处理任务：无需执行，未获取到考评任务 ======");
		}
		
		
		// ======= 解锁 ===========================
		synchronized (this.isProcess) {
			if (this.isProcess) {
				this.isProcess = false;
			}
		}
		
	}
	
	/**
	 * 单个主任务的考核结果生成
	 *
	 * @param teacherEvaluationTask 主任务
	 * @Author fangjin.tao
	 * @updateTime 2022/12/7 11:05
	 */
	@Transactional
	public void gennerResult(TeacherEvaluationTask teacherEvaluationTask) {
		// 计算【主任务】的打分任务是否全部打分。
		Map<String,Object> computerMap = new HashMap<>();
		boolean isTakeScoreSuccess = evaluationUserTaskService.isSuccessByTakeScore(teacherEvaluationTask, computerMap);
		// 统计人数
		Integer sumMemeber = (Integer) computerMap.get("sumMember");
		// 统计总分
		Double sumScore = (Double) computerMap.get("sumScore");
		
		if (isTakeScoreSuccess) {
			// 统计平均分
			Double averageScore = sumScore / sumMemeber;
			// 根据获取任务的考核结果类型生成考核结果X
			// 获取考核类型
			TeacherEvaluationScheme scheme = this.evaluationSchemeService.getById(teacherEvaluationTask.getTescId());
			TeacherEvaluationResult teacherEvaluationResult = null;
			if ("1".equals(scheme.getTescResultType())) {
				// 生成等级制考核结果
				List<TeacherEvaluationGrade> gradeList = this.teacherEvaluationGradeService.listScheId(scheme.getId());
				TeacherEvaluationGrade teacherEvaluationGrade = null;
				if (gradeList != null && gradeList.size() != 0) {
					for (TeacherEvaluationGrade tempTeacherEvaluationGrade : gradeList) {
						if (tempTeacherEvaluationGrade.getBeginScoreArea() <= averageScore && averageScore < tempTeacherEvaluationGrade.getEndScoreArea()) {
							teacherEvaluationGrade = tempTeacherEvaluationGrade;
							break;
						}
					}
					if (teacherEvaluationGrade == null) {
						throw new ApiException("考核任务对应的方案，没有找到对应的等级；不能生成考核结果");
					}
				} else {
					throw new ApiException("考核任务对应的方案，没有考核等级的列表；不能生成考核结果");
				}
				
				teacherEvaluationResult = new TeacherEvaluationResult();
				this.entitySet(teacherEvaluationTask, teacherEvaluationResult, sumScore, sumMemeber, averageScore);
				teacherEvaluationResult.setTereShowType(2);
				// 额外设置级别
				teacherEvaluationResult.setTereShowResultLevel(teacherEvaluationGrade.getTegrLevelName());
			} else {
				// 生成评分制考核结果
				teacherEvaluationResult = new TeacherEvaluationResult();
				this.entitySet(teacherEvaluationTask, teacherEvaluationResult, sumScore, sumMemeber, averageScore);
				teacherEvaluationResult.setTereShowType(1);
			}
			this.save(teacherEvaluationResult);
			
			// 更新主任务的状态
			teacherEvaluationTask.setTetaStatus(Short.valueOf("1"));
			this.evaluationTaskService.update(teacherEvaluationTask.getId(), teacherEvaluationTask);
			
		} else {
			throw new ApiException("打分子任务未全部完成");
		}
		
	}
	
	/**
	 * 封装考核结果对象的值
	 *
	 * @author fangjin.tao
	 * @param: teacherEvaluationTask 主任务对象
	 * @param: teacherEvaluationResult 考核对象
	 * @param: sumScore 打的总分
	 * @param: sumMemeber  总人数
	 * @param: averageScore 平均分
	 * @updateTime 2022/12/7 15:51
	 */
	private void entitySet(TeacherEvaluationTask teacherEvaluationTask, TeacherEvaluationResult teacherEvaluationResult, Double sumScore, Integer sumMemeber, Double averageScore) {
		BeanUtils.copyProperties(teacherEvaluationTask, teacherEvaluationResult);
		teacherEvaluationResult.setCreateTime(Calendar.getInstance().getTime());
		teacherEvaluationResult.setModifyTime(Calendar.getInstance().getTime());
		teacherEvaluationResult.setTereValidScoreSum(sumScore);
		teacherEvaluationResult.setTereValidMemerSum(sumMemeber);
		teacherEvaluationResult.setTereValidScoreAverage(averageScore);
		teacherEvaluationResult.setTereShowResultScore(averageScore);
	}
	
	@Override
	public IPage<TeacherEvaluationResult> getPage(Map<String, Object> params) {
		QueryWrapper<TeacherEvaluationResult> wrapper = new QueryWrapper();
		
		int pageSize = Integer.parseInt(String.valueOf(params.get("pageSize")));
		int pageNum = Integer.parseInt(String.valueOf(params.get("pageNum")));
		
		
		// =========== 考评阶段 =================
		String tetaStageType = (String) params.get("queryStageType"); // 考评阶段
		String acyeId = (String) params.get("queryStageAcyeId"); // 学年
		String tetiId = (String) params.get("queryStageTetiId"); // 学期
		String tetaMonth = (String) params.get("queryStageMonth"); // 月份
		if (StrUtil.isNotEmpty(tetaStageType)) {
			short tetaStageTypeValue = Short.valueOf(tetaStageType);
			if (tetaStageTypeValue != 0) {
				wrapper.eq("tere.teta_stage_type", Short.valueOf(tetaStageType));
				if (StrUtil.isNotEmpty(acyeId)) {
					wrapper.eq("tere.acye_id", Long.valueOf(acyeId));
				}
			}
			
			if (tetaStageTypeValue == 2 && StrUtil.isNotEmpty(acyeId) && StrUtil.isNotEmpty(tetiId)) {
				wrapper.eq("tere.teti_id", Long.valueOf(tetiId));
			} else if (tetaStageTypeValue == 3 && StrUtil.isNotEmpty(acyeId) && StrUtil.isNotEmpty(tetaMonth)) {
				wrapper.eq("tere.teta_month", Long.valueOf(tetaMonth));
			}
			
		}
		
		
		String tetaCoverUserId = (String) params.get("tetaCoverUserId"); // 受评人Id
		if (StrUtil.isNotEmpty(tetaCoverUserId)) {
			wrapper.eq("tere.teta_cover_user_id", tetaCoverUserId);
		}
		
		// 开始时间， 结束时间
		String beginTime = (String) params.get("beginTime");
		String endTime = (String) params.get("endTime");
		if (StrUtil.isNotEmpty(beginTime)) {
			wrapper.gt("tere.create_time", beginTime);
		}
		if (StringUtils.isNotEmpty(endTime)) {
			wrapper.lt("tere.create_time", endTime);
		}
		
		
		String tetaName = (String) params.get("taskName");// 任务名称
		if (StringUtils.isNotEmpty(tetaName)) {
			wrapper.like("tere.teta_name", tetaName);
		}
		//租户
		wrapper.eq("tere.tenant_id", SysUserUtils.getSysUser().getTenantId());
		IPage<TeacherEvaluationResult> page = new Page<TeacherEvaluationResult>(pageNum, pageSize);
		List<TeacherEvaluationResult> dtoList = this.baseMapper.getListBySql(page, wrapper);
		page.setRecords(dtoList);
		return page;
	}
	
	@Override
	public int update(Long id, TeacherEvaluationResult teacherEvaluationResult) {
		int count = this.baseMapper.updateById(teacherEvaluationResult);
		return count;
	}
}
